package com.das.mechanic_base.widget;

import android.graphics.SurfaceTexture;
import android.media.MediaPlayer;
import android.os.Handler;
import android.view.Surface;
import android.view.TextureView;

import java.io.IOException;

/**
 * Video Player
 */
public class X3VideoPlayer {
    private MediaPlayer mediaPlayer;
    private State state = State.IDLE;
    private OnStateChangeListener onStateChangeListener;
    private Handler handler;
    private boolean prePause;
    private X3MyTextureView textureView;

    public X3VideoPlayer() {
        handler = new Handler();
        initMediaPlayer();
    }

    private void initMediaPlayer() {
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setOnPreparedListener(mp -> {
            if (state == State.PREPAREING) {
                if (prePause) {
                    state = State.PAUSE;
                    prePause = false;
                } else {
                    start();
                }
            }
        });
        mediaPlayer.setOnCompletionListener(mp -> {
            state = State.COMPLETE;
            if (onStateChangeListener != null) {
                onStateChangeListener.onComplete();
            }
        });
        mediaPlayer.setOnErrorListener((mp, what, extra) -> {
            if (onStateChangeListener != null) {
                onStateChangeListener.onError();
            }
            return true;
        });
        mediaPlayer.setOnInfoListener((mp, what, extra) -> {
            if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
                if (onStateChangeListener != null) {
                    onStateChangeListener.onRenderingStart();
                }
                refreshProgress();
            }
            return false;
        });

        mediaPlayer.setOnVideoSizeChangedListener((mp, width, height) -> {
            if (textureView != null) {
                textureView.updateTextureViewSizeCenter(mediaPlayer.getVideoWidth(),mediaPlayer.getVideoHeight());
            }
        });
    }

    /**
     * bind TextureView
     */
    public void setTextureView(X3MyTextureView textureView) {
        this.textureView = textureView;
        if (textureView.isAvailable()) {
            mediaPlayer.setSurface(new Surface(textureView.getSurfaceTexture()));
        } else {
            textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
                @Override
                public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                    mediaPlayer.setSurface(new Surface(surface));
                }

                @Override
                public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
                }

                @Override
                public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                    return false;
                }

                @Override
                public void onSurfaceTextureUpdated(SurfaceTexture surface) {
                }
            });
        }
    }

    public boolean isPlaying() {
        return mediaPlayer.isPlaying();
    }

    public void reset() {
        if (mediaPlayer == null) {
            initMediaPlayer();
        }
        mediaPlayer.reset();
        state = State.IDLE;
        if (onStateChangeListener != null) {
            onStateChangeListener.onReset();
            onStateChangeListener = null;
        }
    }

    /**
     * play url
     */
    public void setDataSource(String url) {
        try {
            mediaPlayer.setDataSource(url);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void prepare() {
        try {
            state = State.PREPAREING;
            mediaPlayer.prepareAsync();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void start() {
        if (state == State.PREPAREING || state == State.COMPLETE || state == State.PAUSE) {
            mediaPlayer.start();
            state = State.PLAYING;
        }
    }

    /**
     * 设置进度
     * @param progress
     */
    public void setPrograss(int progress) {
        mediaPlayer.seekTo(progress);
        if (onStateChangeListener != null) {
            onStateChangeListener.onProgressUpdate(progress, mediaPlayer.getDuration());
        }
    }

    public void refreshProgress() {
        if (state != State.PLAYING) {
            return;
        }
        if (handler != null) {
            handler.removeCallbacksAndMessages(null);
        }
        handler.postDelayed(() -> {
            if (mediaPlayer == null) {
                return;
            }
            if (onStateChangeListener != null) {
                onStateChangeListener.onProgressUpdate(mediaPlayer.getCurrentPosition(), mediaPlayer.getDuration());
            }
            refreshProgress();
        }, 100);
    }

    public int getMaxDuration() {
        if (mediaPlayer != null) {
            return mediaPlayer.getDuration();
        }
        return 0;
    }

    public void pause() {
        if (state == State.PREPAREING && !prePause) {
            prePause = true;
            if (onStateChangeListener != null) {
                onStateChangeListener.onPause();
            }
        } else if (state == State.PLAYING) {
            mediaPlayer.pause();
            state = State.PAUSE;
            if (onStateChangeListener != null) {
                onStateChangeListener.onPause();
            }
        }
    }

    public void stop() {
        mediaPlayer.stop();
        state = State.STOP;
        if (onStateChangeListener != null) {
            onStateChangeListener.onStop();
        }
    }

    public void release() {
        mediaPlayer.release();
        mediaPlayer = null;
        handler.removeCallbacksAndMessages(null);
    }

    public State getState() {
        return state;
    }

    public int getDuration() {
        return mediaPlayer.getDuration();
    }

    public void setVolume(float leftVolume, float rightVolume) {
        mediaPlayer.setVolume(leftVolume, rightVolume);
    }

    public void setOnStateChangeListener(OnStateChangeListener onStateChangeListener) {
        this.onStateChangeListener = onStateChangeListener;
    }

    public interface OnStateChangeListener {
        void onReset();

        void onRenderingStart();

        void onProgressUpdate(int prograss,int time);

        void onPause();

        void onStop();

        void onComplete();

        void onError();
    }

    public enum State {
        /**
         * 空闲
         */
        IDLE,
        /**
         * 准备中
         */
        PREPAREING,
        /**
         * 播放中
         */
        PLAYING,
        /**
         * 暂停中
         */
        PAUSE,
        /**
         * 播放停止
         */
        STOP,
        /**
         * 播放结束
         */
        COMPLETE
    }
}